package com.itentbase.match.common.utils;

import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * 流操作工具类
 * 用于转换
 *
 * @author mek
 * @date 2023/4/16
 */
public class StreamsUtil {
    /**
     * 连接字符串
     *
     * @param collection 集合
     * @param func 函数
     * @param delimiter 分隔符
     * @return {@link String}
     */
    public static <T> String joinString(Collection<T> collection, Function<T, String> func, String delimiter) {
        return collection.stream().map(func).collect(Collectors.joining(delimiter));
    }

    /**
     * 将对象的某个属性合并为List
     *
     * @param list 列表
     * @param function 函数
     * @return {@link List}<{@link R}>
     */
    public static <T,R> List<R> mapList(Collection<T> list, Function<T ,R> function){
        return list.stream().map(function).collect(Collectors.toList());
    }

    /**
     * 将对象的某个属性合并为Set
     *
     * @param list 列表
     * @param function 函数
     * @return {@link Set}<{@link R}>
     */
    public static <T, R> Set<R> mapSet(Collection<T> list, Function<T, R> function) {
        return list.stream().map(function).collect(Collectors.toSet());
    }

    /**
     * 过滤器
     *
     * @param list 列表
     * @param predicate 过滤条件
     * @return {@link List}<{@link T}>
     */
    public static <T> List<T> filter(Collection<T> list, Predicate<T> predicate) {
        return list.stream().filter(predicate).collect(Collectors.toList());
    }

    /**
     * 映射为Map
     *
     * @param collection 集合
     * @param keyMapper 键映射器
     * @return {@link Map}<{@link K}, {@link T}>
     */
    public static <T, K> Map<K, T> toMap(Collection<T> collection, Function<T, K> keyMapper) {
        return collection.stream().collect(Collectors.toMap(keyMapper, Function.identity()));
    }

    /**
     * 映射为Map
     *
     * @param collection 集合
     * @param keyMapper 键映射器
     * @param valueMapper 值映射器
     * @return {@link Map}<{@link K}, {@link V}>
     */
    public static <T, K, V> Map<K, V> toMap(Collection<T> collection, Function<T, K> keyMapper, Function<T, V> valueMapper) {
        return collection.stream().collect(Collectors.toMap(keyMapper, valueMapper));
    }

    /**
     * 映射为LinkedHashMap
     *
     * @param collection 集合
     * @param keyMapper 键映射器
     * @param valueMapper 值映射器
     * @return {@link Map}<{@link K}, {@link V}>
     */
    public static <T, K, V> Map<K, V> toLinkedHashMap(Collection<T> collection, Function<T, K> keyMapper, Function<T, V> valueMapper) {
        return collection.stream().collect(Collectors.toMap(keyMapper, valueMapper, (k1, k2) -> k1, LinkedHashMap::new));
    }

    /**
     * 分组
     *
     * @param collection 集合
     * @param classifier 分类器
     * @return {@link Map}<{@link R}, {@link List}<{@link T}>>
     */
    public static <T, R> Map<R, List<T>> groupingBy(Collection<T> collection, Function<T, R> classifier) {
        return collection.stream().collect(Collectors.groupingBy(classifier));
    }

    /**
     * 分组并将分组后的结果再次mapping
     *
     * @param collection 集合
     * @param classifier 分类器
     * @param mappingFunction 映射函数
     * @return {@link Map}<{@link K}, {@link List}<{@link U}>>
     */
    public static <T, K, U> Map<K, List<U>> groupingBy(Collection<T> collection, Function<T, K> classifier, Function<T, U> mappingFunction) {
        return collection.stream()
                .collect(Collectors.groupingBy(classifier, Collectors.mapping(mappingFunction, Collectors.toList())));
    }

    /**
     * 找到第一个
     *
     * @param collection 集合
     * @param predicate 过滤条件
     * @return {@link Optional}<{@link T}>
     */
    public static <T> Optional<T> findFirst(Collection<T> collection, Predicate<T> predicate) {
        return collection
                .stream()
                .filter(predicate)
                .findFirst();
    }

    /**
     * 找到第一个
     *
     * @param collection 集合
     * @param predicate 过滤条件
     * @param notExistSupplier 不存在时的供应商
     * @return {@link T}
     */
    public static <T> T findFirst(Collection<T> collection, Predicate<T> predicate, Supplier<T> notExistSupplier) {
        return collection
                .stream()
                .filter(predicate)
                .findFirst()
                .orElse(notExistSupplier.get());
    }

    /**
     * 找到任何一个
     *
     * @param collection 集合
     * @param predicate 过滤条件
     * @return {@link Optional}<{@link T}>
     */
    public static <T> Optional<T> findAny(Collection<T> collection, Predicate<T> predicate) {
        return collection
                .stream()
                .filter(predicate)
                .findAny();
    }

    /**
     * 找到任何一个
     *
     * @param collection 集合
     * @param predicate 过滤条件
     * @param notExistSupplier 不存在时的供应商
     * @return {@link T}
     */
    public static <T> T findAny(Collection<T> collection, Predicate<T> predicate, Supplier<T> notExistSupplier) {
        return collection
                .stream()
                .filter(predicate)
                .findAny()
                .orElse(notExistSupplier.get());
    }

    /**
     * 任何一个可以匹配
     *
     * @param collection 集合
     * @param predicate 过滤条件
     * @return boolean
     */
    public static <T> boolean anyMatch(Collection<T> collection, Predicate<T> predicate) {
        return collection.stream().anyMatch(predicate);
    }

    /**
     * 所有的都要匹配
     *
     * @param collection 集合
     * @param predicate 过滤条件
     * @return boolean
     */
    public static <T> boolean allMatch(Collection<T> collection, Predicate<T> predicate) {
        return collection.stream().allMatch(predicate);
    }

}

